package top.chukongxiang.monitorservice.javafx.fxml;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import javafx.application.Platform;
import javafx.beans.value.ChangeListener;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import top.chukongxiang.monitorservice.config.SdkServerContextHolder;
import top.chukongxiang.monitorservice.javafx.core.FxContextHolder;
import top.chukongxiang.monitorservice.javafx.fxml.components.LoadingAlert;
import top.chukongxiang.monitorservice.javafx.fxml.components.TreeViewPropertyCellFactory;
import top.chukongxiang.monitorservice.mapper.ServerConfigMapper;
import top.chukongxiang.monitorservice.model.entity.ServerConfig;
import top.chukongxiang.monitorservice.tools.AlertUtil;
import top.chukongxiang.monitorservice.tools.FxBeanUtil;
import top.chukongxiang.monitorservice.tools.H2Util;

import java.io.IOException;
import java.net.URL;
import java.util.List;
import java.util.Objects;
import java.util.ResourceBundle;
import java.util.stream.Collectors;

/**
 * @author 楚孔响
 * @version 1.0
 * @date 2023/10/26 09:44
 */
@Slf4j
public class ServersGui implements Initializable {

    public static final String KEY = "servers";

    @FXML
    public TreeView<ServerConfig> serversTreeView;

    @FXML
    public Button addServerBtn;

    @FXML
    public Button saveBtn;

    @FXML
    public Button closeBtn;

    @FXML
    public Button editServerBtn;

    @FXML
    public VBox pcnvrConfig;

    @FXML
    public PcnvrConfigGui pcnvrConfigController;

    @FXML
    public TabPane tabPane;

    @FXML
    public Button refreshServerBtn;

    private ServerConfig currentServerConfig;

    @FXML
    @SneakyThrows
    @Override
    public void initialize(URL url, ResourceBundle resourceBundle) {
        serversTreeView.setShowRoot(false);
        serversTreeView.setCellFactory(new TreeViewPropertyCellFactory<>(ServerConfig::getName));
        serversTreeView.getSelectionModel().setSelectionMode(SelectionMode.SINGLE);
        serversTreeView.getSelectionModel().selectedItemProperty().addListener(selectedChange());
    }

    public static void show() {
        Platform.runLater(()->{
            try {
                Stage stage = FxContextHolder.get(KEY);
                if (stage == null) {
                    stage = new Stage();
                    FXMLLoader fxmlLoader = new FXMLLoader(SettingGui.class.getClassLoader().getResource("fxml/servers.fxml"));
                    Parent pane = fxmlLoader.load();
                    Scene scene = new Scene(pane);
                    stage.setScene(scene);
                    stage.setTitle("终端/存储配置");
                    // 使用系统风格窗口，标题栏
                    stage.initStyle(StageStyle.DECORATED);
                    // 禁用窗口的最大化功能
                    stage.setResizable(false);
                    FxContextHolder.set(KEY, stage, fxmlLoader.getNamespace());
                }
                loadData();
                stage.show();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        });
    }

    public static void loadData() {
        TreeView<ServerConfig> treeView = FxContextHolder.getNode(KEY, "serversTreeView");
        if (treeView == null) {
            return;
        }
        H2Util.execute(ServerConfigMapper.class, serverConfigMapper -> {
            List<ServerConfig> serverConfigs = serverConfigMapper.selectList(Wrappers.emptyWrapper());
            TreeItem<ServerConfig> root = treeView.getRoot();
            if (root == null) {
                root = new TreeItem<>();
                treeView.setRoot(root);
            }
            ObservableList<TreeItem<ServerConfig>> items = root.getChildren();
            items.clear();
            List<TreeItem<ServerConfig>> list = convert(serverConfigs);
            for (TreeItem<ServerConfig> item : list) {
                item.setExpanded(true);
            }
            items.addAll(list);
        });
    }

    public static <T> List<TreeItem<T>> convert(List<T> list) {
        return list.stream().map(TreeItem::new).collect(Collectors.toList());
    }

    public void addServerBtnClick(ActionEvent event) {
        EditServerGui.show();
    }

    public void editServerBtnClick(ActionEvent event) {
        if (this.currentServerConfig == null) {
            AlertUtil.warn(FxContextHolder.get(KEY), "请选择一项");
            return;
        }
        EditServerGui.show(this.currentServerConfig);
    }

    public void refreshServerBtnClick(ActionEvent event) {
        this.serversTreeView.getSelectionModel().select(-1);
        this.tabPane.getSelectionModel().select(0);
        this.currentServerConfig = null;
        loadData();
    }

    public ChangeListener<TreeItem<ServerConfig>> selectedChange() {
        return (observable, oldValue, newValue) -> {
            if (newValue == null) {
                return;
            }
            this.currentServerConfig = newValue.getValue();
            if (this.currentServerConfig == null) {
                return;
            }
            LoadingAlert loading = AlertUtil.loading(FxContextHolder.get(KEY));
            loading.show();
            Platform.runLater(() -> {
                try {
                    Long serverId = this.currentServerConfig.getId();
                    if (!SdkServerContextHolder.contains(serverId)) {
                        FxBeanUtil.getHcNetSdkService().loginV40(this.currentServerConfig, true);
                    }
                    Integer dvrType = SdkServerContextHolder.getDvrType(serverId);
                    boolean isPcNvrConfig = Objects.equals(202, dvrType);
                    if (isPcNvrConfig) {
                        tabPane.getSelectionModel().select(1);
                        pcnvrConfigController.loadData(this.currentServerConfig);
                        // 加载IP通道参数
                        log.info("{}", SdkServerContextHolder.getDChannelCount(this.currentServerConfig.getId()));
                    } else {
                        tabPane.getSelectionModel().select(0);
                    }
                } finally {
                    loading.close();
                }

            });
        };
    }
}
